package com.zwq.zwqjavanotes.utils;/**
 * @Author gnplum
 * @Date 2025/5/7 17:09
 * @PackageName:com.tellhow.nanrui_report.utils
 * @ClassName: CreateXMLDom
 * @Description: TODO
 * @Version 1.0
 */

import com.zwq.zwqjavanotes.entity.xml.Desc;
import com.zwq.zwqjavanotes.entity.xml.Dtl;
import com.zwq.zwqjavanotes.entity.xml.Dtls;
import com.zwq.zwqjavanotes.entity.xml.ReturnInfo;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @ClassName xml操作工具类
 * @Description TODO
 * @Author @gnplum O_o
 * @Date 2025/5/7 17:09
 * @Version 1.0
 */
public class XMLUtil {
    /**
     * @return java.lang.String
     * @Author gnplum
     * @Description dom4j创建XML
     * @Date 17:12 2025/5/7
     **/
    public static String createXmlByDom4j() {
        // 创建文档
        Document document = DocumentHelper.createDocument();
        // 创建根元素
        Element root = document.addElement("return");

        // 添加 status 元素
        root.addElement("status").setText("success");
        // 添加 msg 元素
        root.addElement("msg").setText("成功");

        // 添加 desc 元素
        Element desc = root.addElement("desc");
        desc.addAttribute("id", "001");
        desc.addElement("proj").setText("测试项目");
        desc.addElement("date").setText("2025-05-06 12:00:00");

        // 添加 dtls 元素
        Element dtls = root.addElement("dtls");
        dtls.addAttribute("remark", "明细列表");

        // 添加第一个 dtl 元素
        Element dtl1 = dtls.addElement("dtl");
        dtl1.addAttribute("column", "at1");
        dtl1.addElement("handleDate").setText("2025-05-06 11:00:00");
        dtl1.addElement("opearUser").setText("张三");

        // 添加第二个 dtl 元素
        Element dtl2 = dtls.addElement("dtl");
        dtl2.addAttribute("column", "at2");
        dtl2.addElement("handleDate").setText("2025-05-06 12:00:00");
        dtl2.addElement("opearUser").setText("李四");

//        // 设置输出格式
//        OutputFormat format = OutputFormat.createPrettyPrint();
//        format.setEncoding("UTF-8");

//        try (XMLWriter writer = new XMLWriter(new FileOutputStream("output.xml"), format)) {
//            // 将文档写入文件
//            writer.write(document);
//            System.out.println("XML 文件创建成功！");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        return document.asXML();
    }

    /**
     * @param xml
     * @return java.lang.String[]
     * @Author gnplum
     * @Description 利用dom4j解析xml - 常规解析
     * @Date 16:09 2025/5/12
     **/
    public static String[] AnalyseXmlByDom4j1(String xml) {
        //示例
        xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<return>\n" +
                "    <status>success</status>\n" +
                "    <msg>成功</msg>\n" +
                "    <desc id=\"001\">\n" +
                "        <proj>测试项目</proj>\n" +
                "        <date>2025-05-06 12:00:00</date>\n" +
                "    </desc>\n" +
                "</return>";
        String status = "";
        String msg = "";
        try {
            // 解析 XML 字符串
            Document document = DocumentHelper.parseText(xml);
            // 获取根元素
            Element root = document.getRootElement();

            // 解析 status 元素
            status = root.elementText("status");
            System.out.println("状态: " + status);

            // 解析 msg 元素
            msg = root.elementText("msg");
            System.out.println("消息: " + msg);

            // 解析 desc 元素及其子元素
            Element desc = root.element("desc");
            String descId = desc.attributeValue("id");
            System.out.println("描述 ID: " + descId);

            String proj = desc.elementText("proj");
            System.out.println("项目名称: " + proj);

            String date = desc.elementText("date");
            System.out.println("日期: " + date);

        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return new String[]{status, msg};
    }

    /**
     * @param xml
     * @return
     * @Author @zwq O_o
     * @Description //dom4j解析xml - 复杂解析
     * @Date 13:50 2025/5/8
     **/
    public static String[] AnalyseXmlByDom4j(String xml) {
//        xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
//                "<return>\n" +
//                "    <status>success</status>\n" +
//                "    <msg>成功</msg>\n" +
//                "    <desc id=\"001\">\n" +
//                "        <proj>测试项目</proj>\n" +
//                "        <date>2025-05-06 12:00:00</date>\n" +
//                "    </desc>\n" +
//                "    <dtls remark=\"明细列表\">\n" +
//                "        <dtl column=\"at1\">\n" +
//                "            <handleDate>2025-05-06 11:00:00</handleDate>\n" +
//                "            <opearUser>张三</opearUser>\n" +
//                "        </dtl>\n" +
//                "        <dtl column=\"at2\">\n" +
//                "            <handleDate>2025-05-06 12:00:00</handleDate>\n" +
//                "            <opearUser>李四</opearUser>\n" +
//                "        </dtl>\n" +
//                "    </dtls>\n" +
//                "</return>";
        String status = "";
        String msg = "";
        try {
            //去掉xml报文头
            String xmlFormat = removeXmlHeader(xml);
            //创建SAXReader对象
            SAXReader reader = new SAXReader();
            //将xml字符串转换为输入流
//            InputStream inputStream = new ByteArrayInputStream(xmlFormat.getBytes(StandardCharsets.UTF_8));
            //读取输入流并生成Document对象
//            Document document = reader.read(inputStream);

            Document document = reader.read(new StringReader(xml));
            //获取根节点
            Element rootElement = document.getRootElement();
            System.out.println(">> 根节点：" + rootElement.getName());

            //解析 - 含判断
//            Element statusElement = rootElement.element("status");
//            if (statusElement != null) {
//                status = statusElement.getText();
//                Element messageElement = rootElement.element("msg");
//                if (messageElement != null) {
//                    msg = messageElement.getText();
//                }
//            }
            status = rootElement.element("status").getText();
            msg = rootElement.element("msg").getText();

//            status=rootElement.elementText("status");
//            msg=rootElement.elementText("msg");

            System.out.println(">> status：" + status);
            System.out.println(">> msg：" + msg);

            //遍历根节点的子节点 desc
            Element dtlsElement = rootElement.element("dtls");
            String remark = dtlsElement.attributeValue("remark");
            System.out.println(">> 属性-remark：" + remark);
            Iterator<Element> iterator = dtlsElement.elementIterator();
            while (iterator.hasNext()) {
                Element element = iterator.next();
                //获取属性
                String column = element.attributeValue("column");
                System.out.println(">> 属性-column==" + column);
                //获取子节点内容
                String handleDate = element.elementText("handleDate");
                String opearUser = element.elementText("opearUser");
                System.out.println(">> 子节点-handleDate==" + handleDate);
                System.out.println(">> 子节点-opearUser==" + opearUser);
            }

        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }
        return new String[]{status, msg};
    }

    public static String createXmlByJAVAXB() {
        try {
            // 创建 ReturnInfo 实例
            ReturnInfo returnInfo = new ReturnInfo();
            returnInfo.setStatus("success");
            returnInfo.setMsg("成功");

            // 创建 Desc 实例
            Desc desc = new Desc();
            desc.setId("001");
            desc.setProj("测试项目");
            desc.setDate("2025-05-06 12:00:00");
            returnInfo.setDesc(desc);

            // 创建 Dtls 实例
            Dtls dtls = new Dtls();
            dtls.setRemark("明细列表");

            // 创建 Dtl 列表
            List<Dtl> dtlList = new ArrayList<>();

            // 创建第一个 Dtl 实例
            Dtl dtl1 = new Dtl();
            dtl1.setColumn("at1");
            dtl1.setHandleDate("2025-05-06 11:00:00");
            dtl1.setOpearUser("张三");
            dtlList.add(dtl1);

            // 创建第二个 Dtl 实例
            Dtl dtl2 = new Dtl();
            dtl2.setColumn("at2");
            dtl2.setHandleDate("2025-05-06 12:00:00");
            dtl2.setOpearUser("李四");
            dtlList.add(dtl2);

            dtls.setDtlList(dtlList);
            returnInfo.setDtls(dtls);

            // 创建 JAXBContext 实例
            JAXBContext jaxbContext = JAXBContext.newInstance(ReturnInfo.class);
            // 创建 Marshaller 实例
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

            // 设置格式化输出
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            // 将 Java 对象转换为 XML 并输出到控制台
//            jaxbMarshaller.marshal(returnInfo, System.out);

            // 创建 StringWriter 来存储 XML 内容
            StringWriter sw = new StringWriter();
            // 将 Java 对象转换为 XML 并写入 StringWriter
            jaxbMarshaller.marshal(returnInfo, sw);

            return sw.toString();
        } catch (JAXBException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param xml
     * @return void
     * @Author gnplum
     * @Description 利用JAVAXB解析xml：Java 对象与 XML 相互转换
     * @Date 16:55 2025/5/12
     **/
    public static void AnalyseXmlByJAVAXB(String xml) {
        //        xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
//                "<return>\n" +
//                "    <status>success</status>\n" +
//                "    <msg>成功</msg>\n" +
//                "    <desc id=\"001\">\n" +
//                "        <proj>测试项目</proj>\n" +
//                "        <date>2025-05-06 12:00:00</date>\n" +
//                "    </desc>\n" +
//                "    <dtls remark=\"明细列表\">\n" +
//                "        <dtl column=\"at1\">\n" +
//                "            <handleDate>2025-05-06 11:00:00</handleDate>\n" +
//                "            <opearUser>张三</opearUser>\n" +
//                "        </dtl>\n" +
//                "        <dtl column=\"at2\">\n" +
//                "            <handleDate>2025-05-06 12:00:00</handleDate>\n" +
//                "            <opearUser>李四</opearUser>\n" +
//                "        </dtl>\n" +
//                "    </dtls>\n" +
//                "</return>";
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(ReturnInfo.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            StringReader reader = new StringReader(xml);
            ReturnInfo returnInfo = (ReturnInfo) unmarshaller.unmarshal(reader);

            System.out.println("状态: " + returnInfo.getStatus());
            System.out.println("消息: " + returnInfo.getMsg());
            System.out.println("描述 ID: " + returnInfo.getDesc().getId());
            System.out.println("项目: " + returnInfo.getDesc().getProj());
            System.out.println("日期: " + returnInfo.getDesc().getDate());
            System.out.println("明细列表备注: " + returnInfo.getDtls().getRemark());

            for (Dtl dtl : returnInfo.getDtls().getDtlList()) {
                System.out.println("列标识: " + dtl.getColumn());
                System.out.println("处理时间: " + dtl.getHandleDate());
                System.out.println("操作用户: " + dtl.getOpearUser());
            }
        } catch (JAXBException e) {
            e.printStackTrace();
        }

    }

    /**
     * @param xml
     * @return
     * @return java.lang.String[]
     * @Author @zwq O_o
     * @Description //w3c解析xml
     * @Date 13:50 2025/5/8
     **/
    public static String[] w3sDomAnalysisXmlDom(String xml) {
        String status = "";
        String message = "";
        try {
            //去掉xml报文头
            String xmlFormat = removeXmlHeader(xml);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
//            Document doc=builder.parse(new ByteArrayInputStream(xml.trim().getBytes()));//UTF-8 可省略
            org.w3c.dom.Document doc = builder.parse(new ByteArrayInputStream(xmlFormat.trim().getBytes("GBK")));//GBK

            //规范化文档
            doc.getDocumentElement().normalize();
            System.out.println(">> 根节点==" + doc.getDocumentElement().getNodeName());

            NodeList nlist = doc.getElementsByTagName("return");
            for (int temp = 0; temp < nlist.getLength(); temp++) {
                Node nNode = nlist.item(temp);
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) nNode;
                    //System.out.println(">> 属性"+element.getAttribute("属性"));
                    status = element.getElementsByTagName("status").item(0).getTextContent();
                    message = element.getElementsByTagName("message").item(0).getTextContent();
                }
            }
        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        } catch (SAXException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return new String[]{status, message};
    }

    /**
     * @param xml
     * @return
     * @return java.lang.String
     * @Author @zwq O_o
     * @Description //去掉xml报文头
     * @Date 13:20 2025/5/8
     **/
    private static String removeXmlHeader(String xml) {
        //去掉xml报文头
        int startIndex = xml.indexOf("?>");
        if (startIndex != -1) {
            return xml.substring(startIndex + 2).trim();
        }
        return xml.trim();
    }
}
